package com.rf.richfitwheel.admin.annotation;

import com.rf.richfitwheel.admin.feignclient.FSysLogService;
import com.rf.richfitwheel.admin.sys.model.SysLog;
import com.rf.richfitwheel.admin.sys.model.User;
import com.rf.richfitwheel.common.utils.UuidUtil;


import org.apache.shiro.SecurityUtils;
import org.apache.shiro.web.subject.WebSubject;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mobile.device.Device;
import org.springframework.mobile.device.DeviceUtils;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;

/**
   *    记录系统用户操作日期切面定义
 * @author Lanvo
 *
 */
@Aspect
@Component
public  class OperateLogAspect {
//本地异常日志记录对象
// private  static  final Logger logger = LoggerFactory.getLogger(OperateLogAspect. class);

 //Controller层切点
 @Pointcut("@annotation(com.rf.richfitwheel.admin.annotation.UserOperateLog)")
 	public  void controllerAspect() {
 }
	/*@Autowired
	private SysLogService fSysLogServices;*/
	@Autowired
	private FSysLogService fSysLogServices;
/**
 * 操作异常记录
 *@descript
 *@param point
 *@param e
 */
@AfterThrowing(pointcut = "controllerAspect()", throwing = "e")  
public  void doAfterThrowing(JoinPoint point, Throwable e) {
	String ip = null;
	String description = e.toString();
	UserOperateLog userOperateLog =null;
	User user=null;
	String clientType = null;
	String mobileUuid = null;
	
	try {
		HttpServletRequest request = (HttpServletRequest) ((WebSubject)SecurityUtils.getSubject()).getServletRequest();
		Device currentDevice = DeviceUtils.getCurrentDevice(request);
		if(currentDevice.isMobile() || currentDevice.isTablet()) {
			//移动端：手机或平板设备需要从请求头中获取设备编号存起来
			clientType = currentDevice.isMobile() ? "2" : "3";
			mobileUuid = request.getHeader("annuityMobileUuid");
		}else {
			clientType = "1";
		}
		ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
		ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
		ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
		ip = request.getHeader("HTTP_CLIENT_IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
		ip = request.getHeader("HTTP_X_FORWARDED_FOR");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
		ip = request.getRemoteAddr();
		}
//		ip = SecurityUtils.getSubject().getSession().getHost();
	} catch (Exception ee) {
		description = ",无法获取登录用户Ip";
	}
	try {

		Signature signature = point.getSignature();    
	    MethodSignature methodSignature = (MethodSignature)signature;    
	    Method targetMethod = methodSignature.getMethod();    
      
	    userOperateLog = (UserOperateLog)targetMethod.getAnnotation(UserOperateLog.class);
	
		// 登录名
		user= (User) SecurityUtils.getSubject().getSession().getAttribute("userSession");
		if (user==null) {
			description = description + ",无法获取登录用户信息！";
		}
	} catch (Exception ee) {
		description = description+",无法获取登录用户信息！";
	}
	//使用spring EL表达式获取参数中的值
//	String bussid = (String) AspectSupportUtils.getKeyValue(point, userOperateLog.bussid());
//	System.out.println("---------业务id：" + bussid);
	SysLog sysLog = new SysLog();
	if(user!=null)
	   sysLog.setUserId(user.getId());

	sysLog.setModule(userOperateLog.module());
	sysLog.setMethods(userOperateLog.methods());
	sysLog.setDescription(e.toString());
	sysLog.setActionTime("0");
	sysLog.setUserIp(ip);
	sysLog.setOperTime(new Date());
	sysLog.setId(UuidUtil.get32UUID());

	sysLog.setBussid(userOperateLog.bussid());//业务id
	sysLog.setClientType(clientType);//终端类型1-PC端、2-手机、3-平板、4-其他设备
	sysLog.setMobileUuid(mobileUuid);//移动端唯一标识
	sysLog.setFunctionNo(userOperateLog.functionNo());//功能编号
	
	try {
//		fSysLogServices.insertLog(sysLog);
		fSysLogServices.save(sysLog);
	}catch (Exception eee){
		eee.printStackTrace();
	}

}
/**
 * 后置通知 用于拦截Controller层记录用户的操作
 *
 * @param point 切点
 */
@Around("controllerAspect()")
public Object doController(ProceedingJoinPoint point) {
	Object result = null;		
	String description = null;
	Long start = 0L;
	Long end = 0L;
	Long time = 0L;
	String ip = null;
	UserOperateLog userOperateLog =null;
	String clientType = null;
	String mobileUuid = null;
	
	// 当前用户
	try{
		Signature signature = point.getSignature();
	    MethodSignature methodSignature = (MethodSignature)signature;    
	    Method targetMethod = methodSignature.getMethod();
		userOperateLog = (UserOperateLog)targetMethod.getAnnotation(UserOperateLog.class);

	    // 执行方法所消耗的时间
		start = System.currentTimeMillis();
		result = point.proceed();
		end = System.currentTimeMillis();
		time = end - start;
	}catch(Throwable e) {
		throw new RuntimeException(e);
	}
	description = userOperateLog.description();
	try {
		HttpServletRequest request = (HttpServletRequest) ((WebSubject)SecurityUtils.getSubject()).getServletRequest();
		Device currentDevice = DeviceUtils.getCurrentDevice(request);
		if(currentDevice.isMobile() || currentDevice.isTablet()) {
			//移动端：手机或平板设备需要从请求头中获取设备编号存起来
			clientType = currentDevice.isMobile() ? "2" : "3";
			mobileUuid = request.getHeader("annuityMobileUuid");
		}else {
			clientType = "1";
		}
		ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
		ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
		ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
		ip = request.getHeader("HTTP_CLIENT_IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
		ip = request.getHeader("HTTP_X_FORWARDED_FOR");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
		ip = request.getRemoteAddr();
		}
//		ip = SecurityUtils.getSubject().getSession().getHost();
	} catch (Exception e) {
		description = description+ ",无法获取登录用户Ip";
	}
	User user=null;
	try {
		// 登录名
		user= (User) SecurityUtils.getSubject().getSession().getAttribute("userSession");
		if (user==null) {
			description = description+ ",无法获取登录用户信息！";
		}
	} catch (Exception e) {
		description = description+ ",无法获取登录用户信息！";
	}
	
	//使用spring EL表达式获取参数中的值
//	String bussid = (String) AspectSupportUtils.getKeyValue(point, userOperateLog.bussid());
//	System.out.println("---------业务id：" + bussid);
	SysLog sysLog = new SysLog();

	if(user!=null)	sysLog.setUserId(user.getId());

	sysLog.setModule(userOperateLog.module());
	sysLog.setMethods(userOperateLog.methods());
	sysLog.setDescription(description);
	sysLog.setActionTime(time.toString());
	sysLog.setUserIp(ip);
	sysLog.setOperTime(new Date());
	sysLog.setId(UuidUtil.get32UUID());
	
	sysLog.setBussid(userOperateLog.bussid());//业务id
	sysLog.setClientType(clientType);//终端类型1-PC端、2-手机、3-平板、4-其他设备
	sysLog.setMobileUuid(mobileUuid);//移动端唯一标识
	sysLog.setFunctionNo(userOperateLog.functionNo());//功能编号
	
	try {
//		fSysLogServices.insertLog(sysLog);
		fSysLogServices.save(sysLog);
	 }catch (Exception e){
		e.printStackTrace();
	}

	return result;
}

}